"""
流体物性计算模块

使用CoolProp库计算水和蒸汽的物性参数
"""

from CoolProp.CoolProp import PropsSI
import numpy as np

class FluidProperties:
    """流体物性计算类"""
    
    def __init__(self):
        """初始化"""
        # 定义水的临界点参数
        self.P_critical = 22.064e6  # 临界压力 (Pa)
        self.T_critical = 647.096   # 临界温度 (K)
        self.P_triple = 611.655     # 三相点压力 (Pa)
        self.T_triple = 273.16      # 三相点温度 (K)
    
    def get_properties(self, pressure, temperature, phase):
        """
        获取指定状态点的流体物性
        
        参数：
        pressure: float, 压力 (Pa)
        temperature: float, 温度 (K)
        phase: str, 相态 ('liquid' 或 'vapor')
        
        返回：
        dict, 包含密度、粘度和焓值的字典
        """
        try:
            # 确保参数在有效范围内
            p = np.clip(pressure, self.P_triple, self.P_critical)
            t = np.clip(temperature, self.T_triple, self.T_critical)
            
            # 获取饱和温度
            T_sat = self.get_saturation_temperature(p)
            
            # 检查是否接近饱和状态（允许1K的误差）
            if abs(t - T_sat) < 1.0:
                if phase == 'liquid':
                    # 使用饱和液体物性
                    return {
                        'density': PropsSI('D', 'P', p, 'Q', 0, 'Water'),
                        'viscosity': PropsSI('V', 'P', p, 'Q', 0, 'Water'),
                        'enthalpy': PropsSI('H', 'P', p, 'Q', 0, 'Water'),
                        'conductivity': PropsSI('L', 'P', p, 'Q', 0, 'Water'),
                        'cp': PropsSI('C', 'P', p, 'Q', 0, 'Water')
                    }
                else:  # vapor
                    # 使用饱和蒸汽物性
                    return {
                        'density': PropsSI('D', 'P', p, 'Q', 1, 'Water'),
                        'viscosity': PropsSI('V', 'P', p, 'Q', 1, 'Water'),
                        'enthalpy': PropsSI('H', 'P', p, 'Q', 1, 'Water'),
                        'conductivity': PropsSI('L', 'P', p, 'Q', 1, 'Water'),
                        'cp': PropsSI('C', 'P', p, 'Q', 1, 'Water')
                    }
            else:
                # 非饱和状态，使用压力和温度计算
                if phase == 'liquid' and t < T_sat:
                    # 亚冷液体
                    return {
                        'density': PropsSI('D', 'P', p, 'T', t, 'Water'),
                        'viscosity': PropsSI('V', 'P', p, 'T', t, 'Water'),
                        'enthalpy': PropsSI('H', 'P', p, 'T', t, 'Water'),
                        'conductivity': PropsSI('L', 'P', p, 'T', t, 'Water'),
                        'cp': PropsSI('C', 'P', p, 'T', t, 'Water')
                    }
                elif phase == 'vapor' and t > T_sat:
                    # 过热蒸汽
                    return {
                        'density': PropsSI('D', 'P', p, 'T', t, 'Water'),
                        'viscosity': PropsSI('V', 'P', p, 'T', t, 'Water'),
                        'enthalpy': PropsSI('H', 'P', p, 'T', t, 'Water'),
                        'conductivity': PropsSI('L', 'P', p, 'T', t, 'Water'),
                        'cp': PropsSI('C', 'P', p, 'T', t, 'Water')
                    }
                else:
                    # 如果相态与温度不匹配，使用饱和物性
                    Q = 0 if phase == 'liquid' else 1
                    return {
                        'density': PropsSI('D', 'P', p, 'Q', Q, 'Water'),
                        'viscosity': PropsSI('V', 'P', p, 'Q', Q, 'Water'),
                        'enthalpy': PropsSI('H', 'P', p, 'Q', Q, 'Water'),
                        'conductivity': PropsSI('L', 'P', p, 'Q', Q, 'Water'),
                        'cp': PropsSI('C', 'P', p, 'Q', Q, 'Water')
                    }
        except Exception as e:
            print(f"警告：物性计算失败 (P={pressure}, T={temperature})")
            print(f"错误信息: {str(e)}")
            # 返回一个合理的默认值而不是None
            if phase == 'liquid':
                return {
                    'density': 1000.0,      # 常温常压下的水密度
                    'viscosity': 1e-3,      # 常温常压下的水粘度
                    'enthalpy': 4.2e5,      # 近似值
                    'conductivity': 0.6,     # 常温常压下的水导热系数
                    'cp': 4200.0            # 常温常压下的水比热容
                }
            else:
                return {
                    'density': 1.0,         # 近似值
                    'viscosity': 1e-5,      # 近似值
                    'enthalpy': 2.5e6,      # 近似值
                    'conductivity': 0.025,   # 近似值
                    'cp': 2000.0            # 近似值
                }
    
    def get_saturation_temperature(self, pressure):
        """
        获取给定压力下的饱和温度
        
        参数：
        pressure: float, 压力 (Pa)
        
        返回：
        float, 饱和温度 (K)
        """
        try:
            # 确保压力在有效范围内
            p = np.clip(pressure, self.P_triple, self.P_critical)
            return PropsSI('T', 'P', p, 'Q', 0, 'Water')
        except Exception as e:
            print(f"警告：饱和温度计算失败 (P={pressure})")
            print(f"错误信息: {str(e)}")
            # 返回一个近似值
            return 373.15  # 1个大气压下的饱和温度
    
    def get_latent_heat(self, pressure):
        """
        获取给定压力下的汽化潜热
        
        参数：
        pressure: float, 压力 (Pa)
        
        返回：
        float, 汽化潜热 (J/kg)
        """
        try:
            # 确保压力在有效范围内
            p = np.clip(pressure, self.P_triple, self.P_critical)
            h_g = PropsSI('H', 'P', p, 'Q', 1, 'Water')  # 饱和蒸汽焓
            h_f = PropsSI('H', 'P', p, 'Q', 0, 'Water')  # 饱和水焓
            return h_g - h_f
        except Exception as e:
            print(f"警告：汽化潜热计算失败 (P={pressure})")
            print(f"错误信息: {str(e)}")
            # 返回一个近似值
            return 2.257e6  # 1个大气压下的汽化潜热
    
    def get_surface_tension(self, temperature):
        """
        获取给定温度下的表面张力
        
        参数：
        temperature: float, 温度 (K)
        
        返回：
        float, 表面张力 (N/m)
        """
        try:
            # 确保温度在有效范围内
            t = np.clip(temperature, self.T_triple, self.T_critical)
            return PropsSI('I', 'T', t, 'Q', 0, 'Water')
        except Exception as e:
            print(f"警告：表面张力计算失败 (T={temperature})")
            print(f"错误信息: {str(e)}")
            # 返回一个近似值
            return 0.072  # 常温下的水的表面张力